package com.kehutong.contact.app;

import com.kehutong.common.DoveClient;
import com.kehutong.common.enums.Gender;
import com.kehutong.common.util.SnowflakeIdUtils;
import com.kehutong.common.util.Token;
import com.kehutong.contact.entity.*;
import com.kehutong.contact.enums.RelationType;
import com.kehutong.contact.enums.ResidentType;
import com.kehutong.contact.service.impl.ResidentServiceImpl;
import com.kehutong.contact.util.ResidentTagUtil;
import org.coraframework.converter.Converter;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.MvcAction;
import org.coraframework.mvc.http.Bean;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.JSONResult;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.util.EnumUtil;
import org.coraframework.util.Objects;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 住户对外接口
 *
 * @Author: liukunlong
 * @Date: 21/2/8 上午9:43
 */
@MvcAction
@ReqMapping("/kht-bin/resident")
public class ResidentAction {
    private static final Logger logger = LoggerFactory.getLogger(ResidentAction.class);

    @Inject
    private ResidentServiceImpl residentService;

    @Inject
    private JdbcSession jdbcSession;

    @Inject
    private DoveClient doveClient;

    /**
     * 获取住户信息
     *
     * @param token      用户信息
     * @param jsonObject 查询条件
     * @return 住户列表
     * @throws Exception 异常
     */
    @ReqMapping("/list")
    public JSONResult list(Token token, JSONObject jsonObject) throws Exception {

        int type = jsonObject.getIntValue("type");

        if (type == 2) {//公海列表
            //查询没有员工跟进的住户信息
            JSONObject residentJsonObject = new JSONObject();
            residentJsonObject.put("isExistUser", "0");
            Result.success(residentService.getResidentList(residentJsonObject));

        }
        //todo 用户离职以后状态为离职待继承的数据客户数据当前用户需要看不到？
        jsonObject.put("userIds", token.getUuid());
        Page<Resident> page = residentService.getResidentList(jsonObject);
        return Result.success(page);
    }


    /**
     * 获取住户信息
     *
     * @param token      用户信息
     * @param jsonObject
     * @return
     * @throws Exception
     */
    @Bean(copy = true)
    @ReqMapping("/get")
    public Object getResident(Token token, JSONObject jsonObject) throws Exception {
        jsonObject.put("userIds", token.getUuid());
        jsonObject.put("id", jsonObject.getString("id"));
        Page<Resident> page = residentService.getResidentList(jsonObject);
        List<Resident> residentList = page.getList();
        return Result.success(residentList.get(0));
    }

    /**
     * 更新住户信息
     *
     * @param token    用户信息
     * @param resident 住户对象
     * @return 结果对象
     * @throws Exception 异常
     */
    @Bean(copy = true)
    @ReqMapping("/update")
    public Object updateResident(Token token, Resident resident) throws Exception {
        //设置当前住户跟进人信息
        //resident.setUserId(token.getUuid());
        residentService.updateResident(resident);
        return Result.success();
    }

    /**
     * 认领住户信息
     * 原来逻辑
     * 1.根据联系人跟进主键获取当前用户领取的联系人跟进信息
     * 2.获取领取的联系人信息
     * 3.调用腾讯接口指派领取的联系人信息给当前用户
     * 4。同步联系人数据(因为上一步的指派理论上腾信已经把联系人放到了当前员工下面,只要同步数据就有了)
     * 5.删除联系人中信息中就旧的跟进人信息
     * 6.逻辑删除旧的联系人跟进信息
     * 7.获取当前用户,当前联系人的跟进记录
     * 8.如果跟进记录为空则新增当前联系人的跟进记录(已离职员工的跟进记录为蓝本)
     * 9.如果不为空则更新当前用户跟进记录为 继承状态“离职继承中”，继承自上一个离职员工ID，更新客户类别
     * <p>
     * 现有逻辑
     * 增加跟进人信息
     *
     * @param token          登录录用信息
     * @param id             住户id
     * @param handoverUserid 离职员工id
     * @return 成功信息
     * @throws Exception 异常
     */
    @ReqMapping("/gain")
    public Object gain(Token token, String id, String handoverUserid) throws Exception {
        String userId = token.getUserId();
        Resident resident = residentService.getResidentById(id);
        List<String> users = resident.getUsers();
        if (users.contains(userId)) {
            return Result.error(0, "你已经是当前住户的跟进人,不需要再次认领");
        }
        //新增跟进员工
        users.add(userId);
        residentService.updateResident(resident);
        return Result.success();
    }


    /**
     * 首次编辑
     * 根据不同类型跟新相关数据
     * 1.更新备注
     * 2.更新住户分类
     * 3.更新标签
     * 4.更新更近状态
     * 5.新增跟进记录
     *
     * @param token      用户信息
     * @param jsonObject 参数对象
     * @return 住户信息
     * @throws Exception 异常
     */
    @ReqMapping("/fastEdit")
    public Object fastEdit(Token token, JSONObject jsonObject) throws Exception {
        Resident resident = residentService.getResidentById(jsonObject.getString("id"));
        //Contact contact = Pool.get(Contact.class, jsonObject.getString("id"));
        //String followId = ContactFollow.toId(contact.getId(), session.getUserId());
        //ContactFollow follow = Pool.get(ContactFollow.class, followId);

        final int type = jsonObject.getIntValue("type");
        switch (type) {
            case 1:
                //todo 更新备注,暂时没有
                //follow.setRemarkName(jsonObject.getString("value"));
                //contactService.editRemark(follow, contact.getUserId());
                break;
            case 2:
                //更新住户分类
                resident.setClassifyId(jsonObject.getString("label"));
                resident.setClassifyName(jsonObject.getString("value"));
                //follow.setTypeId(jsonObject.getString("label"));
                //follow.setTypeName(jsonObject.getString("value"));
                break;
            case 3:
                //更新标签
                List<String> tagIds = toList(jsonObject, "label");
                List<String> tagNames = toList(jsonObject, "value");
                if (tagIds.size() != tagNames.size()) {
                    return Result.error(0, "标签数量错误");
                }

                //标记企业微信的标签
                //requestMarkTag(follow, tagIds, contact.getUserId());

                //todo 将标签序列号成为字符串存储然后赋值
                ResidentTagUtil.setTag(token.getUserId(), tagIds, tagNames, resident);
                //follow.setTagIds(tagIds);
                //follow.setTagNames(tagNames);
                break;
            case 4:
                //更新跟进状态编号及名称
                resident.setStateId(jsonObject.getString("label"));
                resident.setStateName(jsonObject.getString("value"));
                //follow.setStatusId(jsonObject.getString("label"));
                //follow.setStatusName(jsonObject.getString("value"));
                break;
            case 5:
                //新增跟进记录
                /*TrackRecord record = Pool.newInstance(TrackRecord.class);
                record.setDesc(jsonObject.getString("value"));
                record.setMbrCode(token.getUserId());
                record.setMbrName(token.getUsername());
                record.setUserId(resident.getId());
                jdbcSession.insert(record);*/


                //获取住户的跟进记录 todo 需要测试
                doveClient.post("/crm/trackRecord/saveTrackRecord", (http) -> {
                    http.addHeader("companyNo", token.getCompanyNo());
                    JSONObject body = new JSONObject();
                    body.put("desc", jsonObject.getString("value"));
                    body.put("mbrCode", token.getUserId());
                    body.put("mbrName", token.getUsername());
                    body.put("userId", resident.getId());
                    http.setBody(body.toJSONString());
                });
                //follow.setRecordId(record.getId());
                //follow.setRecordName(record.getDesc());
                break;
        }


        residentService.updateResident(resident);
        //jdbcSession.updateById(follow);

        return Result.success(resident);
    }

    /**
     * 编辑 住户相关信息
     *
     * @throws Exception 异常
     */
    @ReqMapping("/edit")
    public Object edit(Token session, JSONObject jsonObject) throws Exception {
        Resident resident = residentService.getResidentById(jsonObject.getString("id"));
        String statusId = jsonObject.getString("statusId");
        String statusName = jsonObject.getString("statusName");
        String typeId = jsonObject.getString("typeId");
        String typeName = jsonObject.getString("typeName");
        String corpName = jsonObject.getString("corpName");
        String officeName = jsonObject.getString("officeName");
//        String mobile = jsonObject.getString("mobile");
        Gender gender = EnumUtil.getEnum(Gender.class, jsonObject.getString("gender"));
        resident.setStateId(statusId);
        resident.setStateName(statusName);
        resident.setClassifyId(typeId);
        resident.setClassifyName(typeName);
        resident.setCorpName(corpName);
        resident.setOfferName(officeName);
        resident.setGender(gender);
        resident.setBirthDay(Objects.nonEmpty(jsonObject.getString("birthday")) ? Converter.toLocalDateTime(jsonObject.getString("birthday")) : null);
        //contact.setEmail(jsonObject.getString("email"));
        //contact.setRemark(jsonObject.getString("remark"));
        //设置省市区
        /*if (Objects.isNull(jsonObject.getString("provinceNo"))) {
            String regionNo = jsonObject.getString("areaCode");
            setProvinceCityRegion(contact, regionNo);
        }else {
            contact.setRegionNo(jsonObject.getString("regionNo"));
            contact.setRegionName(jsonObject.getString("regionName"));
            contact.setCityNo(jsonObject.getString("cityNo"));
            contact.setCityName(jsonObject.getString("cityName"));
            contact.setProvinceNo(jsonObject.getString("provinceNo"));
            contact.setProvinceName(jsonObject.getString("provinceName"));
        }*/


        residentService.updateResident(resident);
        //jdbcSession.updateById(contact);

        //批量新增住户车辆信息,先删除后插入方法
        JSONArray residentCarJSONArray = jsonObject.getJSONArray("residentCarList");
        if (Objects.nonEmpty(residentCarJSONArray)) {
            JSONObject residentCarJsonObject = new JSONObject();
            residentCarJsonObject.put("residentNo", resident.getId());
            List<ResidentCar> residentCarList = residentService.getResidentCarList(residentCarJsonObject).getList();
            //删除住户下面所有车辆信息
            jdbcSession.deleteById(residentCarList);

            residentCarJSONArray.forEach((obj) -> {
                try {
                    JSONObject residentCarJSONObject = (JSONObject) obj;
                    ResidentCar residentCar = Pool.newInstance(ResidentCar.class);
                    residentCar.setResidentNo(resident.getId());
                    //车位号
                    residentCar.setParkingNo(residentCarJSONObject.getString("parkingNo"));
                    //车牌号
                    residentCar.setCarNo(residentCarJSONObject.getString("carNo"));
                    //品牌
                    residentCar.setCarBrand(residentCarJSONObject.getString("carBrand"));
                    //型号
                    residentCar.setCarModel(residentCarJSONObject.getString("carModel"));
                    //车颜色
                    residentCar.setCarColor(residentCarJSONObject.getString("carColor"));
                    residentService.saveResidentCar(residentCar);
                } catch (Exception exception) {
                    exception.printStackTrace();
                }

            });
        }


        //批量新增住户家庭信息,先删除后插入方法
        JSONArray residentFamilyJSONArray = jsonObject.getJSONArray("residentFamilyList");
        if (Objects.nonEmpty(residentFamilyJSONArray)) {
            JSONObject residentFamilyJsonObject = new JSONObject();
            residentFamilyJsonObject.put("residentNo", resident.getId());
            List<ResidentFamily> residentFamilyList = residentService.getResidentFamilyList(residentFamilyJsonObject).getList();
            //删除住户下面所有车辆信息
            jdbcSession.deleteById(residentFamilyList);

            residentFamilyJSONArray.forEach((obj) -> {
                try {
                    JSONObject residentFamilyJSONObject = (JSONObject) obj;
                    ResidentFamily residentFamily = Pool.newInstance(ResidentFamily.class);
                    residentFamily.setResidentNo(resident.getId());
                    //姓名
                    residentFamily.setName(residentFamilyJSONObject.getString("name"));
                    //手机
                    residentFamily.setMobile(residentFamilyJSONObject.getString("mobile"));
                    //性别
                    residentFamily.setGender(EnumUtil.getEnum(Gender.class, jsonObject.getString("gender")));
                    //身份证
                    residentFamily.setCardNo(residentFamilyJSONObject.getString("cardNo"));
                    //和住户关系
                    residentFamily.setType(EnumUtil.getEnum(RelationType.class, jsonObject.getString("type")));
                    residentService.saveResidentFamily(residentFamily);
                } catch (Exception exception) {
                    exception.printStackTrace();
                }

            });
        }


        //批量新增住户家庭信息,先删除后插入方法
        JSONArray residentHouseJSONArray = jsonObject.getJSONArray("residentHouseList");
        if (Objects.nonEmpty(residentHouseJSONArray)) {
            JSONObject residentHouseJsonObject = new JSONObject();
            residentHouseJsonObject.put("residentNo", resident.getId());
            List<ResidentHouse> residentFamilyList = residentService.getResidentHouseList(residentHouseJsonObject).getList();
            //删除住户下面所有房屋
            jdbcSession.deleteById(residentFamilyList);

            residentHouseJSONArray.forEach((obj) -> {
                try {
                    JSONObject residentHouseJSONObject = (JSONObject) obj;
                    ResidentHouse residentHouse = Pool.newInstance(ResidentHouse.class);
                    residentHouse.setResidentNo(resident.getId());
                    //房屋编号
                    residentHouse.setHouseNo(residentHouseJSONObject.getString("houseNo"));
                    //住户关系
                    residentHouse.setType(EnumUtil.getEnum(ResidentType.class, jsonObject.getString("type")));
                    residentService.saveResidentHouse(residentHouse);
                } catch (Exception exception) {
                    exception.printStackTrace();
                }

            });
        }


        //todo 是否删除 目前支持单个车辆更新
        String residentCarId = jsonObject.getString("residentCarId");
        if (Objects.isNull(residentCarId)) {
            ResidentCar residentCar = Pool.newInstance(ResidentCar.class);
            residentCar.setResidentNo(resident.getId());
            //车位号
            residentCar.setParkingNo(jsonObject.getString("parkingNo"));
            //车牌号
            residentCar.setCarNo(jsonObject.getString("carNo"));
            //品牌
            residentCar.setCarBrand(jsonObject.getString("carBrand"));
            //型号
            residentCar.setCarModel(jsonObject.getString("carModel"));
            //车颜色
            residentCar.setCarColor(jsonObject.getString("carColor"));
            residentService.saveResidentCar(residentCar);
        } else {
            ResidentCar residentCar = residentService.getResidentCarById(residentCarId);
            //车位号
            residentCar.setParkingNo(jsonObject.getString("parkingNo"));
            //车牌号
            residentCar.setCarNo(jsonObject.getString("carNo"));
            //品牌
            residentCar.setCarBrand(jsonObject.getString("carBrand"));
            //型号
            residentCar.setCarModel(jsonObject.getString("carModel"));
            //车颜色
            residentCar.setCarColor(jsonObject.getString("carColor"));
            residentService.updateResidentCar(residentCar);
        }


        return Result.success(resident);
    }


    @ReqMapping("/getContact")
    public Object getResident(Token token, String residentId) throws Exception {
        if (Objects.isEmpty(residentId)) {
            return Result.error(0, "客户不存在");
        }
        //住户信息
        Resident resident = residentService.getResidentById(residentId);

        //住户车辆信息
        JSONObject carJsonObject = new JSONObject();
        carJsonObject.put("residentNo", resident.getId());
        Page<ResidentCar> carPage = residentService.getResidentCarList(carJsonObject);

        //住户家庭信息
        JSONObject familyJsonObject = new JSONObject();
        familyJsonObject.put("residentNo", resident.getId());
        List<ResidentFamily> familyList = residentService.getResidentFamilyList(familyJsonObject).getList();


        //获取住户的跟进记录 todo 需要测试
        JSONObject trackRecordJsonObject = doveClient.post("/crm/trackRecord/getTrackRecordList", (http) -> {
            http.addHeader("companyNo", token.getCompanyNo());
            JSONObject body = new JSONObject();
            body.put("userId", residentId);
            http.setBody(body.toJSONString());
        });
        JSONArray records = trackRecordJsonObject.getJSONArray("data");
        logger.debug("records:{}", records.toJSONString());
        /*final List<TrackRecord> records = jdbcSession.findArray(TrackRecord.class)
                .eq("userId", residentId)
                .order("createTime", "DESC")
                .exe();*/


        /*WebChat webChat = SignJDBCSession.findOne(WebChat.class)
                .eq("companyNo", contact.getCompanyNo())
                .eq("unionid", contact.getUnionid())
                .eq("deleted", false).exe();*/

        JSONObject resultJson = new JSONObject();
        resultJson.put("complaintCount", 0);
        resultJson.put("repairsCount", 0);
        resultJson.put("evaluationCount", 0);
        resultJson.put("totalCount", 0);

        //todo 没有加入公众号会员逻辑
/*        if(Objects.nonNull(webChat)) {
            List<ContactLog> logs = SignJDBCSession.findArray(ContactLog.class)
                    .eq("contactNo", webChat.getId())
                    .order("createTime","desc")
                    .exe();
            resultJson.put("logs", logs);

            String statusSql = "select count(*) as count from t_repairs where companyNo = ? and createById = ? and repairsStatus = ?;";
            Integer evaluationCount = SignJDBCSession.findOne(statusSql,new Object[]{session.getCompanyNo(), webChat.getId(), 4},rs -> {
                return rs.getInt("count");
            });
            resultJson.put("evaluationCount", evaluationCount);

            String typeSql = "select type,count(*) as count from t_repairs where {}";
            List<JSONObject> types = SignJDBCSession.findArray(typeSql, rs -> {
                JSONObject json = new JSONObject();
                json.put("type", rs.getString("type"));
                json.put("count", rs.getString("count"));
                return json;
            })
                    .eq("companyNo", session.getCompanyNo())
                    .eq("createById", webChat.getId())
                    .eq("deleted",false)
                    .groupBy("type")
                    .exe();


            types.forEach(json -> {
                OperationType type = EnumUtil.getEnum(OperationType.class, json.getString("type"));
                if(OperationType.COMPLAINT == type){
                    resultJson.put("complaintCount",json.getString("count"));
                }else if (OperationType.REPAIRS == type){
                    resultJson.put("repairsCount",json.getString("count"));
                }
            });

            CustomerHouse customerHouse = SignJDBCSession.findOne(CustomerHouse.class)
                    .eq("residentId", webChat.getId())
                    .eq("deleted", false)
                    .eq("def", true)
                    .exe();

            if(Objects.nonNull(customerHouse)){
                House house = Pool.get(House.class, customerHouse.getHouseId());
                resultJson.put("house", house);
            }

            List<CustomerHouse> customerHouses = SignJDBCSession.findArray(CustomerHouse.class)
                    .eq("residentId", webChat.getId())
                    .eq("deleted", false)
                    .exe();

            if(Objects.nonNull(customerHouses)){
                List<String> houseIds = customerHouses.stream().map(CustomerHouse :: getHouseId).collect(Collectors.toList());

                if(Objects.nonEmpty(houseIds)){
                    String totalSql = "select sum(total) as count from t_charge_bill where {}";
                    List<BigDecimal> totalCount = SignJDBCSession.findArray(totalSql, rs -> {
                        return rs.getBigDecimal("count");
                    })
                            .eq("companyNo", session.getCompanyNo())
                            .in("houseNo",houseIds)
                            .eq("paidState", BillPaidState.UNPAID.getId())
                            .eq("enableState", BillEnableState.ENABLE.getId())
                            .eq("deleted", false)
                            .exe();
                    resultJson.put("totalCount", totalCount.get(0));
                }else{
                    resultJson.put("totalCount", BigDecimal.ZERO);
                }
            }
        }*/

        resultJson.put("contact", resident);
        //resultJson.put("follow", follow);
        resultJson.put("car", carPage.getList());
        resultJson.put("family", familyList);
        resultJson.put("records", records);

        return Result.success(resultJson);
    }

    /**
     * 查看3名离职或交接的员工信息
     * todo 获取3名离职或交接的员工信息逻辑怎么写？是否砍掉该功能
     *
     * @param token 用户嘻信息
     * @param id    标志
     * @return
     */
    @ReqMapping("/getHandoverEmployeeForThree")
    public Object getHandoverEmployeeForThree(Token token, String id) {
        /*ContactFollow contactFollow = Pool.get(ContactFollow.class, id);


        List<JSONObject> contactsJson = new ArrayList<>();
        // 第一个
        if (Objects.nonNull(contactFollow)) {
            setContactsJson(session, contactFollow, contactsJson);
        }

        ContactFollow secondContactFollow = setContactsJsonAndGetContactFollow(session, contactFollow, contactsJson);
        if (Objects.isNull(secondContactFollow)) {
            return Result.success(Collections.emptyList());
        }

        setContactsJsonAndGetContactFollow(session, secondContactFollow, contactsJson);*/

        return Result.success(null);
    }


    private List<String> toList(JSONObject json, String name) {
        final String jsonArray = json.getString(name);

        final List<String> list = new ArrayList<>();
        if (Objects.isEmpty(jsonArray)) {
            return list;
        }

        String[] strs = jsonArray.split(",");
        for (int i = 0, j = strs.length; i < j; i++) {
            if (Objects.nonEmpty(strs[i])) {
                list.add(strs[i]);
            }
        }

        return list;
    }


    /**
     * 1.绑定住户
     * 如果当前住户手机号跟后台住户信息类型的住户信息手机号一致直接绑定。
     * 如果当前住户手机号跟后台住户信息类型的住户信息手机号不一致,或者不存在住户信息则提交给管理人员审核,审核通过如果没有创建住户类型住户信息，然后进行绑定房产。
     * 2.绑定家属
     * 如果当前申请绑定家属的手机号与当前住户下的家庭信息中存在的手机号一致则直接绑定.
     * 如果当前申请绑定家属的手机号与当前住户下的家庭信息中存在的手机号不一致或者不存在则提交住户审核,审核通过，如果没有家庭信息则创建当前住户的家庭信息，然后绑定房产
     * 3.绑定租户
     * 如果当前租户手机号跟后台租户类型类型的住户信息手机号一致直接绑定，则直接微信房产绑定。
     * 如果当前租户手机号跟后台组合信息类型的住户信息手机号不一致,或者不存在则租户信息提交给住户审核审核,审核通过创建租户类型住户信息，然后进行绑定房产。
     *
     * @param token
     * @param jsonObject
     * @return
     */
    @ReqMapping("/bind")
    public Object bind(Token token, JSONObject jsonObject) {
        return null;
    }


    @ReqMapping("/initOwnerNo")
    public Object initOwnerNo(JSONObject jsonObject) {
        List<ResidentHouse>  dbResidentHouseList=jdbcSession.findArray(ResidentHouse.class)
                .isNull("ownerNo")
                .exe(false);
        if(Objects.nonEmpty(dbResidentHouseList)){
            dbResidentHouseList.forEach(v->{
                // 如果数据库中已经存在则取出相应编号
                List<ResidentHouse> residentHouseList =
                        jdbcSession.findArray(ResidentHouse.class).eq("communityNo", v.getCommunityNo()).and().eq("residentNo", v.getResidentNo()).isNotNull("ownerNo").exe(false);
                if (Objects.nonEmpty(residentHouseList)) {
                    ResidentHouse dbData=residentHouseList.get(0);
                    v.setOwnerNo(dbData.getOwnerNo());
                }
                if (Objects.isBlank(v.getOwnerNo())) {
                    SnowflakeIdUtils snowflakeIdUtils = new SnowflakeIdUtils(0);
                    long id = snowflakeIdUtils.nextId();
                    v.setOwnerNo(v.getHouseType().getCode() + id);
                }
                jdbcSession.updateById(v);
            });
        }
        return Result.success();
    }

}
